#include "dbng.hpp"
#include "mysql.hpp"//注意，使用什么数据库时就需要include对应的hpp文件，里面是对相关函数的反射封装
//#include "sqlite.hpp" //例如使用sqlite时，则包含sqlite.hpp
using namespace ormpp;

struct person {
//   std::optional<int> age; // 可以插入null值
  std::string name;
  int id;
};
REGISTER_AUTO_KEY(person, id)
REGISTER_CONFLICT_KEY(person, name)
// REGISTER_CONFLICT_KEY(person, name, age)
REFLECTION(person, id, name)
// REFLECTION_WITH_NAME(person, "CUSTOM_TABLE_NAME", id, name, age)
// REFLECTION_ALIAS(person, "CUSTOM_TABLE_NAME",
//                  FLDALIAS(&person::id, "person_id"),
//                  FLDALIAS(&person::name, "person_name"),
//                  FLDALIAS(&person::age, "person_age"));

int main() {
  person p = {"test1", 2};
  person p1 = {"test2", 3};
  person p2 = {"test3", 4};
  std::vector<person> v{p1, p2};

  dbng<mysql> mysql;
  mysql.connect("localhost", "root", "3567851", "itstar");
  mysql.create_datatable<person>(ormpp_auto_key{"id"});

  mysql.insert(p);
  mysql.insert(v);
  auto id1 = mysql.get_insert_id_after_insert<person>(p);
  auto id2 = mysql.get_insert_id_after_insert<person>(v);

  mysql.update(p);
  mysql.update(v);
  mysql.update(p, "id=1");

  mysql.replace(p);
  mysql.replace(v);

  // 更新指定字段
  mysql.update_some<&person::name>(p);
  mysql.update_some<&person::name>(v);

  auto result = mysql.query_s<person>();
  for (auto &person : result) {
    std::cout << person.id << " " << person.name
              << std::endl;
  }

  mysql.delete_records<person>();

  // transaction
  mysql.begin();
  for (int i = 0; i < 10; ++i) {
    person s = {"tom", 19};
    if (!mysql.insert(s)) {
      mysql.rollback();
      return -1;
    }
  }
  mysql.commit();
  return 0;
}